Completed
Push — master ( 944ff2...cd9c80 )
by Andres
01:00
created

angular.controller(ꞌct_matterꞌ)   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
c 1
b 0
f 0
nc 4
dl 0
loc 27
rs 8.439
nop 1
1
/**
2
 matter
3
 Component that handles generators, resource creation, isotopes and decay.
4
5
 @namespace Components
6
 */
7
'use strict';
8
9
angular.module('game').component('matter', {
10
  templateUrl: 'views/matter.html',
11
  controller: 'ct_matter',
12
  controllerAs: 'ct'
13
});
14
15
angular.module('game').controller('ct_matter', ['state', 'visibility', 'data', 'util', 'reaction',
16
function (state, visibility, data, util, reaction) {
17
  let ct = this;
18
  ct.state = state;
19
  ct.data = data;
20
  let buyAmount = [1,10,25,100,'max'];
21
22
  /* Proceses the decay of radiactive isotopes. It uses a random draw based on the
23
  half life to decide how many atoms decay, and then spreads them over different
24
  decay forms proportionally. */
25
  function processDecay(player) {
26
    // for each radiactive isotope
27
    for (let i = 0; i < data.radioisotopes.length; i++) {
28
      let resource = data.radioisotopes[i];
29
      if (player.resources[resource].unlocked) {
30
        let number = player.resources[resource].number;
31
        let halfLife = data.resources[resource].decay.half_life;
32
        let production = util.randomDraw(number, Math.log(2) / halfLife);
33
34
        if (production === 0) {
35
          continue;
36
        }
37
38
        // we decrease the number of radioactive element
39
        //player.resources[resource].number -= production;
40
41
        // and decay products
42
        let type;
43
        for (type of Object.values(data.resources[resource].decay.decay_types)) {
44
          let decayNumber = Math.floor(production * type.ratio);
45
          production -= decayNumber;
46
          reaction.react(decayNumber, type.reaction, player);
47
        }
48
        reaction.react(production, type.reaction, player);
0 ignored issues
show
Bug introduced by
The variable type seems to not be initialized for all possible execution paths.
Loading history...
49
      }
50
    }
51
  }
52
53
  /* Proceses the generation for each element. It generates isotopes with a random
54
  draw proportionally to their probability. */
55
  function processGenerators(player) {
56
    // we will simulate the production of isotopes proportional to their ratio
57
    for (let element in player.elements) {
58
      if (player.elements[element].unlocked === false) {
59
        continue;
60
      }
61
      // prepare an array with the isotopes
62
      let isotopes = Object.keys(data.elements[element].isotopes);
63
      let remaining = ct.elementProduction(player, element);
64
      // we will create a random draw recalculate the mean and std
65
      for (let i = 0; i < isotopes.length - 1; i++) {
66
        // first we need to adjust the ratio for the remaining isotopes
67
        let remainingRatioSum = 0;
68
        for (let j = i; j < isotopes.length; j++) {
69
          remainingRatioSum += data.resources[isotopes[j]].ratio;
70
        }
71
72
        // we calculate the production with a random draw
73
        let p = data.resources[isotopes[i]].ratio / remainingRatioSum;
74
        let production = util.randomDraw(remaining, p);
75
76
        if (production > 0) {
77
          // assign the player the produced isotope
78
          player.resources[isotopes[i]].number += production;
79
          if (!player.resources[isotopes[i]].unlocked) {
80
            player.resources[isotopes[i]].unlocked = true;
81
            state.addNew(isotopes[i]);
82
          }
83
        }
84
        remaining -= production;
85
      }
86
      // the last isotope is just the remaining production that hasn't been consumed
87
      if (remaining > 0) {
88
        let last = isotopes[isotopes.length - 1];
89
        player.resources[last].number += remaining;
90
        if (!player.resources[last].unlocked) {
91
          player.resources[last].unlocked = true;
92
          state.addNew(last);
93
        }
94
      }
95
    }
96
  }
97
98
  function update(player) {
99
    processDecay(player);
100
    processGenerators(player);
101
  }
102
103
  function generatorPrice (name, level) {
104
    return data.generators[name].price * Math.pow(data.constants.GENERATOR_PRICE_INCREASE, level);
105
  }
106
107
  ct.maxCanBuy = function (player, name, element){
108
    let level = player.elements[element].generators[name];
109
    let i = 0;
110
    let currency = data.elements[element].main;
111
    let price = generatorPrice(name, level);
112
    // we need a loop since we use the ceil operator
113
    while (player.resources[currency].number >= price) {
114
      i++;
115
      price += generatorPrice(name, level + i);
116
    }
117
    return i;
118
  };
119
120
  ct.generatorTotalPrice = function(player, name, element, number) {
121
    if(number === 'max'){
122
      number = ct.maxCanBuy(player, name, element);
123
    }
124
    let level = player.elements[element].generators[name];
125
    let totalPrice = 0;
126
    for(let i = 0; i < number; i++){
127
      let price = generatorPrice(name, level + i);
128
      totalPrice += Math.ceil(price);
129
    }
130
    return totalPrice;
131
  };
132
133
  ct.buyGenerators = function(player, name, element, number) {
134
    if(number === 'max'){
135
        number = ct.maxCanBuy(player, name, element);
136
    }
137
    let price = this.generatorTotalPrice(player, name, element, number);
138
    let currency = data.elements[element].main;
139
    if(ct.canBuy(player, element, price)){
140
      player.resources[currency].number -= price;
141
      player.elements[element].generators[name]+= number;
142
    }
143
  };
144
145
  ct.canBuy = function(player, element, price) {
146
    let currency = data.elements[element].main;
147
    if(price > player.resources[currency].number){
148
      return false;
149
    }
150
    return true;
151
  };
152
153
  ct.generatorProduction = function(player, name, element) {
154
    let baseProduction = data.generators[name].power;
155
    return upgradedProduction(player, baseProduction, name, element);
156
  };
157
158
  ct.tierProduction = function(player, name, element) {
159
    let baseProduction = data.generators[name].power *
160
      player.elements[element].generators[name];
161
    return upgradedProduction(player, baseProduction, name, element);
162
  };
163
164
  /* Upgraded production includes upgrades, exotic matter and dark matter. */
165
  function upgradedProduction(player, production, name, element) {
166
    for (let up in data.generators[name].upgrades) {
167
      if (player.elements[element].upgrades[data.generators[name].upgrades[up]]) {
168
        let power = data.upgrades[data.generators[name].upgrades[up]].power;
169
        production = upgradeApply(production, power);
170
      }
171
    }
172
    let exotic = data.elements[element].exotic;
173
    production *= (1 + player.resources[exotic].number * data.constants.EXOTIC_POWER) *
174
                  (1 + player.resources.dark_matter.number * data.constants.DARK_POWER);
175
    return Math.floor(production);
176
  }
177
178
  function upgradeApply(resource, power) {
179
    return resource * power;
180
  }
181
182
  ct.elementProduction = function(player, element) {
183
    let total = 0;
184
    for (let tier in data.generators) {
185
      total += ct.tierProduction(player, tier, element);
186
    }
187
    return total;
188
  };
189
190
  ct.visibleGenerators = function(currentElement) {
191
    return visibility.visible(data.generators, isGeneratorVisible, currentElement);
192
  };
193
194
  function isGeneratorVisible(name, currentElement) {
195
    let generator = data.generators[name];
196
    for (let dep of generator.deps) {
197
      if (state.player.elements[currentElement].generators[dep] === 0) {
198
        return false;
199
      }
200
    }
201
202
    return true;
203
  }
204
205
  ct.nextBuyAmount = function() {
206
    state.buyIndex = (state.buyIndex + 1) % buyAmount.length;
207
  };
208
209
  ct.getbuyAmount = function() {
210
    return buyAmount[state.buyIndex];
211
  };
212
213
  state.registerUpdate('matter', update);
214
}]);
215